/*
$LastChangedBy: ssidek@gmail.com $
$LastChangedDate: 2014-06-07 06:56:27 +0000 (Sat, 07 Jun 2014) $
$Revision: 110 $

Description:
        Student Registration System Main Program

*/

import java.util.*;    // ArrayList, Collections, Comparator, Scanner, TreeSet
import java.io.*;      // File, FileNotFoundException, IOException
import java.lang.*;    // NumberFormatException
import org.apache.commons.lang3.StringUtils; 

public class StudentRegistrationSystem implements Runnable {
	// Instance variables
	private ArrayList<Student> studentList      = new ArrayList<Student>();
    private TreeSet<Course>    courseList       = new TreeSet<Course>();
	private Student            student;
	private String             alignFormat      = "%s %n";

	// Constants
	static  String COURSE_LIST_FILE	            = "CourseList.txt";
	static  String STUDENT_LIST_FILE            = "StudentList.txt";
 
    static  StringBuilder WELCOME_MESSAGE       = new StringBuilder(
            "#####################################################################\n" +
            "##                                                                 ##\n" +
            "##               Team C: Student Registration System               ##\n" +
            "##                                                                 ##\n" +
            "#####################################################################\n"
            );
    static  StringBuilder DISPLAY_COURSE_HEADER = new StringBuilder(
            "+----+-------------+--------------+--------------+------------------+\n" +
            "| ID | Course Name | Max/Enrolled | Start - End  | Course Summary   |\n" +
            "+----+-------------+--------------+--------------+------------------+"
            );

    /**
    * main()
    */
    public static void main(String args[]) {
        new StudentRegistrationSystem().run();
    }

    /**
    * run() is called by main()
    */
    public void run() {
        Boolean timeToExit = false;
        Boolean loggedIn   = false;
        Student student    = null;
        String  selection;

        Scanner userInput = new Scanner(System.in);

        clearScreen();
        System.out.println("\n" + WELCOME_MESSAGE + "\n");

        // Display Course List
        System.out.println("Here is a list of the courses offered:");
        // created a header	
        System.out.println(DISPLAY_COURSE_HEADER);
	
		// this is the course list that will print below the header
		courseList = CourseList.readCourseList(COURSE_LIST_FILE);
		displayCourseList();

        // Student List
        studentList = StudentList.readStudentList(STUDENT_LIST_FILE, courseList);


		while (!loggedIn) {
			// Prompt user to make a selection
			System.out.println();
            System.out.println("Menu:");
			System.out.println("1. Login");
			System.out.println("2. Create New Account");
			System.out.println("3. Exit");
			System.out.println("");
			System.out.print("Enter your selection: ");
			selection = userInput.next();

            try {
                switch ( Integer.parseInt(selection) ) {
                    // get user credentials and verify that he's an existing student
                    case 1:
                        student = loginStudent();
                        break;
                    // create a new account
                    case 2:
                        student = createStudentAccount();
                        break;
                    case 3:
                        timeToExit = true;
                        break;
                    default:
                        System.out.println("Invalid selection.");
                        break;
                }
            } catch (NumberFormatException e) {
                System.out.println("Invalid selection.");
            }
            // If login or account creation was successful, the student is now logged
            // in.
            if (student != null) {
                loggedIn = true;
                System.out.println("\nWelcome, " + this.student.getLogin() + "!");
            }
            if (timeToExit) {
                break;
            }
        }

        // Let the user choose to register or unregister, then repeat, stopping only 
        // when the user decides to exit.
        while (!timeToExit) {
            // Display the list of courses this student is registered for
            if (student.getCourseCount() == 0) {
                System.out.println("\nYou haven't registered to any course.");
            } else {
            	System.out.println("\nHere is your list of courses:");
            	System.out.println(DISPLAY_COURSE_HEADER);
              
            TreeSet<Course> studentCourses = student.getCourseSet();
               	for (Course c : studentCourses) {
               		System.out.println(c.getCourseInfo());
               	}
            }
            System.out.println();
                        
            // Prompt user to make a selection
            if (student.getCourseCount() == 0) {
                System.out.println("Menu:");
                System.out.println("1. Register for a course");
                System.out.println("2. Exit"); 
                System.out.println("");
                System.out.print("Enter your selection: ");
                selection = userInput.next();

                try {
                    switch ( Integer.parseInt(selection) ) {
                        // get the user's selection of which course to add, and add him to it
                        case 1:
                            registerCourse();
                            break;
                        case 2:
                            timeToExit = true;
                            break;
                        default:
                            System.out.println("Invalid selection.");
                            break;
                    }
                } catch (NumberFormatException e) {
                    System.out.println("Invalid selection.");
                }
            } else {
                System.out.println("Menu:");
                System.out.println("1. Register for a course");
                System.out.println("2. Unregister for a course");
                System.out.println("3. Exit"); 
                System.out.println("");
                System.out.print("Enter your selection: ");
                selection = userInput.next();

                try {
                    switch ( Integer.parseInt(selection) ) {
                        // get the user's selection of which course to add, and add him to it
                        case 1:
                            registerCourse();
                            break;
                        // get the user's selection of which course to unregister from,
                        // and unregister him
                        case 2:
                            unregisterCourse();
                            break;
                        case 3:
                            timeToExit = true;
                            break;
                        default:
                            System.out.println("Invalid selection.");
                            break;
                    }
                } catch (NumberFormatException e) {
                    System.out.println("Invalid selection.");
                }
            }

            // Pause for 2 seconds before continuing, to let the user read feedback
            // from the last action.
            try {
                Thread.sleep(2000);
            } catch ( java.lang.InterruptedException ie) {
                System.out.println(ie);
            }
        }
                
        // Write out the course list and student list, saving changes made during
        // this session.
        CourseList.writeCourseList(this.courseList, COURSE_LIST_FILE);
        StudentList.writeStudentList(this.studentList, STUDENT_LIST_FILE);
                
        // Done, now exit.
        System.out.println("\nThank you for using the Student Registration System!");
        System.exit(0);
    }

    /**
    * displayCourseList()
    */
    public void displayCourseList() {
        for (Course c : courseList) {
            System.out.format(alignFormat, c.getCourseInfo());
        }
    }

    /**
    * createStudentAccount()
    * @return student Student object
    */
    public Student createStudentAccount() {
        String loginName;

        Scanner userLogin = new Scanner(System.in);

        System.out.print("\nEnter new login name: ");
        loginName = userLogin.next();

		Student test1 = StudentList.getStudent(loginName, studentList);
		
		if (test1 != null) {
			System.out.println("Found student named " + test1.getLogin() + 
			" try another username");
		} else {       
            System.out.println("\nCreating a new student..");
            student = new Student(loginName);
            StudentList.addStudent(student, studentList);
		}

        return student;
    }

	/**
	* loginStudent()
	* @return student Student object
	*/
	public Student loginStudent() {
		String  loginName = "";

        Scanner userLogin = new Scanner(System.in);

        System.out.print("\nEnter your login name: ");
        loginName = userLogin.next();

        student = StudentList.getStudent(loginName, studentList);

        if  (student == null){
            System.out.println("User not found! Enter 2 to create an account!");
        }

        return student;
    }

	/**
	* registerCourse()
	*/
	public void registerCourse() {
		Boolean registered = false;
        String  selection;
		Course  selectedCourse;
		
		System.out.println("\nThe following courses are still open:");
        System.out.println(DISPLAY_COURSE_HEADER);

        // Display non-full courses
        for (Course c : courseList) {
            if (!c.isCourseFull()) {
                System.out.println(c.getCourseInfo());
            }
        }

        // Get the user's input (a course ID).  
        Scanner userInput = new Scanner(System.in);
        System.out.print("\nEnter a course ID: ");
        selection = userInput.next();

        // Find the course with this course ID.  
        selectedCourse = CourseList.getCourse(selection, this.courseList);
        if (selectedCourse == null) {
            System.out.println("Invalid input.");
        } else {
            // Try to register the student for this course.
            registered = this.student.registerCourse(selectedCourse);
        }

        // Display the result of this selection.
        if (registered) {
            System.out.println("Registration successful.");
        } else {
            System.out.println("Registration failed.");
        }    
    }

	/**
	* unregisterCourse()
	*/
	public void unregisterCourse() {
		Boolean unregisterStatus = false;
		String  selection;
		Course  selectedCourse;

		// List all registered course for this student
        if (student.getCourseCount()==0) {
            System.out.println("You haven't registered to any course.");
        } else {
            System.out.println("\nHere is your list of courses:");
            System.out.println(DISPLAY_COURSE_HEADER);
         
            TreeSet<Course> studentCourses = student.getCourseSet();
            for (Course c : studentCourses) {
                System.out.println(c.getCourseInfo());
            }  
        }

		// Get user input to unregister course
		Scanner userInput = new Scanner(System.in);
		System.out.print("\nEnter courseID to unregister: ");
		selection = userInput.next();

		selectedCourse = CourseList.getCourse(selection, courseList);
		if (selectedCourse == null) {
			System.out.println("Invalid input.");
		} else {
			unregisterStatus = student.unregisterCourse(selectedCourse);
		}

		// Unregistration status
		if (unregisterStatus) {
			System.out.println("Unregistration successful.");
		} else {
			System.out.println("Unregistration failed.");
		}
	}

    /**
    * clearScreen()
    */
    public void clearScreen() {
        try {
            if (System.getProperty( "os.name" ).startsWith( "Windows" )) {
                Runtime.getRuntime().exec("cls");
            } else {
                Runtime.getRuntime().exec("clear");
            }
        } catch (IOException e) {
            for(int i = 0; i < 100; i++) {
                System.out.println();
            }
        }
    }

}
